﻿using System.IO;
using System.IO.Compression;
using System.Linq;
using BookiFramework.Abstracts;
using BookiFramework.Abstracts.Files.Compression;

namespace BookiFramework.Files.Compression
{
    public class Zipper : IZipper
    {
        public OperationResult UnZipToDirectory(string zipFile, string directoryToExtract)
        {
            if (!File.Exists(zipFile)) return OperationResult.Fail("The file not exists.");

            using (var zipFileToOpen = new FileStream(zipFile, FileMode.Open))
            using (var archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Update))
                archive.ExtractToDirectory(directoryToExtract);

            return OperationResult.Correct();
        }

        public OperationResult Zip(string fileTarget, params string[] files)
        {
            if (files.Any(x => !File.Exists(x))) return OperationResult.Fail("One or more files don't exist.");

            using (var zipFileToOpen = new FileStream(fileTarget, FileMode.OpenOrCreate))
            using (var archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Create))
            {
                foreach (var file in files)
                {
                    var name = Path.GetFileName(file);
                    archive.CreateEntryFromFile(file, name);
                }
            }
            return OperationResult.Correct();
        }

        public MemoryStream Zip(bool disposeStream = false, params string[] files)
        {
            var zipFileToOpen = new MemoryStream();

            var archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Create);

            foreach (var file in files)
            {
                var name = Path.GetFileName(file);
                var entry = archive.CreateEntry(name);
                using (var writer = new StreamWriter(entry.Open()))
                {
                    var content = File.ReadAllBytes(file);
                    writer.Write(content);
                    writer.Flush();
                }
            }

            if (disposeStream)
                archive.Dispose();

            return zipFileToOpen;

        }
    }
}
